package hedron.editor;

import static hedron.i18n.Internationalization._;
import hedron.Activator;
import hedron.Application;
import hedron.db.model.Stock;
import hedron.db.model.StockGroup;
import hedron.dialog.GroupingDialog;
import hedron.dialog.StockDialog;
import hedron.dialog.StringDialog;
import hedron.editorinput.DummyEditorInput;
import hedron.ui.UIFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorSite;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ScrolledForm;
import org.eclipse.ui.part.EditorPart;

public class StockEditor extends EditorPart {
	public static final String ID = "HEDRON.StockEditor";

	private FormToolkit toolkit;
	private ScrolledForm form;

	Text filterField;
	Table groupsTable;
	Table stocksTable;

	Table groupingTable;
	Table groupedTable;

	List<StockGroup> groups;
	List<Stock> stocks;

	ArrayList<Stock> groupingStocks;
	ArrayList<Stock> groupedStocks;

	Listener sortListener;
	int currentSorting = 0, previousSorting = 0;

	String[] sortColumns = { "GROUP_NAME", "STOCK_NAME", "STOCK_CODE" };

	String[] columnNames = { _("Column.Group"), _("Column.Stock"), _("Column.Barcode") };

	String[] groupingNames = { _("Column.Stock"), _("Column.Quantity") };

	void refresh() {

		if (groups != null) groups.clear();
		groups = Application.STOCKS.getStockGroups(filterField.getText());

		groupsTable.setRedraw(false);
		groupsTable.removeAll();
		for (StockGroup group : groups) {
			TableItem item = new TableItem(groupsTable, SWT.NONE);
			item.setData(group);
			item.setText(0, group.GROUP_NAME);
		}
		groupsTable.getColumn(0).pack();
		groupsTable.setRedraw(true);

		if (stocks != null) stocks.clear();
		stocks = Application.STOCKS.getStocks(filterField.getText(), sortColumns[currentSorting],
				previousSorting == currentSorting ? "ASC" : "DESC");

		stocksTable.setRedraw(false);
		stocksTable.removeAll();
		for (Stock stock : stocks) {
			TableItem item = new TableItem(stocksTable, SWT.NONE);
			item.setData(stock);
			item.setText(0, stock.GROUP_NAME);
			item.setText(1, stock.STOCK_NAME);
			item.setText(2, stock.STOCK_CODE);
		}
		for (int i = 0; i < 3; i++) {
			stocksTable.getColumn(i).pack();
		}
		stocksTable.setRedraw(true);
	}

	void refreshGrouping() {
		if (groupingStocks != null) groupingStocks.clear();
		groupingStocks = Application.STOCKS.getGroupingStocks(null);

		groupingTable.setRedraw(false);
		int selection = groupingTable.getSelectionIndex();
		groupingTable.removeAll();
		for (Stock stock : groupingStocks) {
			TableItem item = new TableItem(groupingTable, SWT.NONE);
			item.setData(stock);
			item.setText(0, stock.STOCK_NAME);
		}
		groupingTable.getColumn(0).pack();
		if (selection < groupingTable.getItemCount()) {
			groupingTable.setSelection(selection);
		}
		groupingTable.setRedraw(true);

		groupedTable.setRedraw(false);
		groupedTable.removeAll();
		groupedTable.setRedraw(true);
	}

	void refreshGrouped() {
		int selection = groupingTable.getSelectionIndex();
		if (selection >= 0) {
			Stock groupingStock = (Stock) groupingTable.getItem(selection).getData();

			groupedTable.setRedraw(false);
			if (groupedStocks != null) groupedStocks.clear();
			groupedStocks = Application.STOCKS.getGroupedStocks(groupingStock);
			groupedTable.removeAll();
			for (Stock stock : groupedStocks) {
				TableItem item = new TableItem(groupedTable, SWT.NONE);
				item.setData(stock);
				item.setText(0, stock.STOCK_NAME);
				item.setText(1, "" + stock.QTY);
			}
			groupedTable.getColumn(0).pack();
			groupedTable.getColumn(1).pack();
			groupedTable.setRedraw(true);
		}
	}

	private void newGroup() {
		StringDialog stringDialog = new StringDialog(Application.getActiveWorkbench().getShell(),
				_("Editor.Stock.Text.New"), "");
		if (stringDialog.open() == Window.OK && stringDialog.getString().trim().length() > 0) {
			StockGroup stockGroup = new StockGroup();
			stockGroup.GROUP_NAME = stringDialog.getString().trim();
			stockGroup.store();
		}
		refresh();
	}

	private void editGroup() {
		int selection = groupsTable.getSelectionIndex();
		if (selection >= 0) {
			StockGroup stockGroup = (StockGroup) groupsTable.getItem(selection).getData();
			StringDialog stringDialog = new StringDialog(Application.getActiveWorkbench().getShell(),
					_("Editor.Stock.Text.Rename") + " '" + stockGroup.GROUP_NAME + "':", stockGroup.GROUP_NAME);
			if (stringDialog.open() == Window.OK && stringDialog.getString().trim().length() > 0) {
				stockGroup.GROUP_NAME = stringDialog.getString().trim();
				stockGroup.store();
			}
			refresh();
		}
	}

	private void createStock() {
		Stock stock = new Stock();
		StockDialog dialog = new StockDialog(Application.getActiveWorkbench().getShell(), stock);
		if (dialog.open() == Window.OK) {
			if (stock.isValid()) {
				stock.store();
			}
		}
		refresh();

	}

	private void editStock() {
		int selection = stocksTable.getSelectionIndex();
		if (selection >= 0) {
			Stock stock = (Stock) stocksTable.getItem(selection).getData();
			StockDialog dialog = new StockDialog(Application.getActiveWorkbench().getShell(), stock);
			if (dialog.open() == Window.OK) {
				if (stock.isValid()) {
					stock.store();
				}
			}
			refresh();
		}
	}

	private void scrollStocks() {
		int selection = groupsTable.getSelectionIndex();
		if (selection >= 0 && currentSorting == 0) {
			StockGroup stockGroup = (StockGroup) groupsTable.getItem(selection).getData();
			long groupId = stockGroup.getID();
			for (int i = 0; i < stocks.size(); i++) {
				if (stocks.get(i).GROUP_ID == groupId) {
					stocksTable.setTopIndex(i);
					break;
				}
			}
		}
	}

	@Override
	public void init(IEditorSite site, IEditorInput input) throws PartInitException {
		setSite(site);
		setInput(input);
		setTitleImage(Activator.getImage("icons/stock.png"));

		sortListener = new Listener() {
			public void handleEvent(Event e) {
				if (e.widget instanceof TableColumn) {
					int sortColumn = 0;
					for (; sortColumn < columnNames.length; sortColumn++) {
						if (columnNames[sortColumn].equals(((TableColumn) e.widget).getText())) {
							break;
						}
					}
					currentSorting = sortColumn;
					stocksTable.setSortColumn((TableColumn) e.widget);
					if (previousSorting != currentSorting) {
						stocksTable.setSortDirection(SWT.UP);
						previousSorting = currentSorting;
					} else {
						stocksTable.setSortDirection(SWT.DOWN);
						previousSorting = -1;
					}
					refresh();
				}
			}
		};
	}

	public void dispose() {
		toolkit.dispose();
		super.dispose();
	}

	@Override
	public void setFocus() {}

	private static final String layout = "<layout align=\"FILL\" valign=\"FILL\">"
			+ "<section text=\"Editor.Stock.Section.Search\" columns=\"3\" align=\"FILL\" valign=\"BEGINING\">"
			+ "     <label text=\"Editor.Stock.Label.Search\" align=\"BEGINING\" valign=\"CENTER\"/>"
			+ "      <text  id=\"filterField\" align=\"FILL\" valign=\"CENTER\"/>"
			+ "      <button id=\"searchButton\" text=\"Editor.Stock.Button.Search\" icon=\"icons/search.png\" width=\"80\" height=\"20\" align=\"BEGINING\" valign=\"CENTER\"/>"
			+ "</section>"
			+ "<splitter vertical=\"70\" align=\"FILL\" valign=\"FILL\">"
			+ "    <splitter horizontal=\"40\" align=\"FILL\" valign=\"FILL\">"
			+ "      <section text=\"Column.Groups\" columns=\"2\" align=\"FILL\" valign=\"FILL\">"
			+ "         <table id=\"groupsTable\" fullselection=\"true\" align=\"FILL\" valign=\"FILL\"/>"
			+ "         <container align=\"BEGINING\" valign=\"FILL\">"
			+ "            <button id=\"addGroupButton\" text=\"Editor.Stock.Button.Add\" width=\"80\" height=\"20\" align=\"BEGINING\" valign=\"BEGINNING\"/>"
			+ "            <button id=\"renameGroupButton\" text=\"Editor.Stock.Button.Rename\" width=\"80\" height=\"20\" align=\"BEGINING\" valign=\"BEGINNING\"/>"
			+ "         </container>"
			+ "      </section>"
			+ "      <section text=\"Editor.Stock.Section.Groups\" columns=\"2\" align=\"FILL\" valign=\"FILL\">"
			+ "         <table id=\"stocksTable\" fullselection=\"true\" align=\"FILL\" valign=\"FILL\"/>"
			+ "         <container align=\"BEGINING\" valign=\"FILL\">"
			+ "            <button id=\"addStockButton\" text=\"Editor.Stock.Button.Add\" width=\"80\" height=\"20\" align=\"BEGINING\" valign=\"BEGINNING\"/>"
			+ "            <button id=\"renameStockButton\" text=\"Editor.Stock.Button.Rename\" width=\"80\" height=\"20\" align=\"BEGINING\" valign=\"BEGINNING\"/>"
			+ "            <button id=\"groupStockButton\" text=\"Editor.Stock.Button.Grouping\" width=\"80\" height=\"20\" align=\"BEGINING\" valign=\"BEGINNING\"/>"
			+ "         </container>"
			+ "      </section>"
			+ "    </splitter>"
			+ "    <splitter horizontal=\"40\" align=\"FILL\" valign=\"FILL\">"
			+ "      <section text=\"Editor.Stock.Section.GroupedStocks\" columns=\"2\" align=\"FILL\" valign=\"FILL\">"
			+ "         <table id=\"groupingTable\" fullselection=\"true\" align=\"FILL\" valign=\"FILL\"/>"
			+ "         <container align=\"BEGINING\" valign=\"FILL\">"
			+ "            <button id=\"deleteGroupingButton\" text=\"Editor.Stock.Button.Delete\" width=\"80\" height=\"20\" align=\"BEGINING\" valign=\"BEGINNING\"/>"
			+ "         </container>"
			+ "      </section>"
			+ "      <section text=\"Editor.Stock.Section.GroupedStocks\" columns=\"2\" align=\"FILL\" valign=\"FILL\">"
			+ "         <table id=\"groupedTable\" fullselection=\"true\" align=\"FILL\" valign=\"FILL\"/>"
			+ "         <container align=\"BEGINING\" valign=\"FILL\">"
			+ "            <button id=\"editGroupingButton\" text=\"Editor.Stock.Button.Edit\" width=\"80\" height=\"20\" align=\"BEGINING\" valign=\"BEGINNING\"/>"
			+ "         </container>"
			+ "      </section>"
			+ "    </splitter>"			
			+ "</splitter>" 
			+ "</layout>";

	@Override
	public void createPartControl(Composite parent) {
		toolkit = new FormToolkit(parent.getDisplay());
		form = toolkit.createScrolledForm(parent);

		form.setText(_("Editor.Stock.Title"));
		form.setBackgroundImage(Activator.getImage("icons/form_background.png"));
		Map<String, Control> components = UIFactory.createUI(form.getBody(), layout, toolkit);

		{
			filterField = (Text) components.get("filterField");
			final Button searchButton = (Button) components.get("searchButton");

			filterField.addKeyListener(new KeyListener() {
				@Override
				public void keyReleased(KeyEvent e) {
					if (e.keyCode == 13) {
						refresh();
					}
				}

				@Override
				public void keyPressed(KeyEvent e) {}
			});

			searchButton.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					refresh();
				}
			});
		}
		{
			groupsTable = (Table) components.get("groupsTable");
			{
				TableColumn column = new TableColumn(groupsTable, SWT.NONE);
				column.setText(_("Editor.Stock.Groups.Title"));
			}
			groupsTable.setHeaderVisible(true);
			groupsTable.setLinesVisible(true);

			groupsTable.addListener(SWT.MouseDoubleClick, new Listener() {
				@Override
				public void handleEvent(Event event) {
					editGroup();
				}
			});

			groupsTable.addListener(SWT.Selection, new Listener() {
				@Override
				public void handleEvent(Event event) {
					scrollStocks();
				}
			});

			final Button addGroupButton = (Button) components.get("addGroupButton");
			addGroupButton.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					newGroup();
				}
			});

			final Button renameGroupButton = (Button) components.get("renameGroupButton");
			renameGroupButton.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					editGroup();
				}
			});

		}

		{
			stocksTable = (Table) components.get("stocksTable");
			for (String columnName : columnNames) {
				TableColumn column = new TableColumn(stocksTable, SWT.NONE);
				column.setText(columnName);
				column.addListener(SWT.Selection, sortListener);
			}

			stocksTable.setHeaderVisible(true);
			stocksTable.setLinesVisible(true);

			stocksTable.addListener(SWT.MouseDoubleClick, new Listener() {
				@Override
				public void handleEvent(Event event) {
					editStock();
				}
			});

			final Button addStockButton = (Button) components.get("addStockButton");
			addStockButton.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					createStock();
				}
			});

			final Button renameStockButton = (Button) components.get("renameStockButton");
			renameStockButton.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					editStock();
				}
			});

			final Button groupStockButton = (Button) components.get("groupStockButton");
			groupStockButton.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					int selection = stocksTable.getSelectionIndex();
					if (selection >= 0) {
						Stock stock = (Stock) stocksTable.getItem(selection).getData();

						GroupingDialog dialog = new GroupingDialog(Application.getActiveWorkbench().getShell(), stock);
						dialog.open();
						refreshGrouping();
					}
				}
			});
		}

		{
			groupingTable = (Table) components.get("groupingTable");
			{
				TableColumn column = new TableColumn(groupingTable, SWT.NONE);
				column.setText(_("Column.GroupingStock"));
			}
			groupingTable.setHeaderVisible(true);
			groupingTable.setLinesVisible(true);

			groupingTable.addListener(SWT.Selection, new Listener() {
				@Override
				public void handleEvent(Event event) {
					refreshGrouped();
				}
			});
			final Button deleteGroupingButton = (Button) components.get("deleteGroupingButton");
			deleteGroupingButton.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					int selection = groupingTable.getSelectionIndex();
					if (selection >= 0) {
						Stock groupingStock = (Stock) groupingTable.getItem(selection).getData();
						Application.STOCKS.deleteGroupedStocksFor(groupingStock);
					}
					refreshGrouping();
				}
			});
		}
		{

			groupedTable = (Table) components.get("groupedTable");
			{
				TableColumn column = new TableColumn(groupedTable, SWT.NONE);
				column.setText(groupingNames[0]);
			}
			{
				TableColumn column = new TableColumn(groupedTable, SWT.NONE | SWT.RIGHT);
				column.setText(groupingNames[1]);
			}
			groupedTable.setHeaderVisible(true);
			groupedTable.setLinesVisible(true);

			final Button editGroupingButton = (Button) components.get("editGroupingButton");
			editGroupingButton.addSelectionListener(new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					int selection = groupingTable.getSelectionIndex();
					if (selection >= 0) {
						Stock groupingStock = (Stock) groupingTable.getItem(selection).getData();

						GroupingDialog dialog = new GroupingDialog(Application.getActiveWorkbench().getShell(),
								groupingStock);
						dialog.open();
						refreshGrouping();
						refreshGrouped();
					}
				}
			});
		}

		// toolbar buttons
		{
			Action action = new Action("print", Action.AS_PUSH_BUTTON) { //$NON-NLS-1$
				public void run() {
					IWorkbenchPage page = getSite().getPage();
					try {
						final TableColumn[] columns = stocksTable.getColumns();
						final StringBuilder html = new StringBuilder();

						html.append("<HTML><head><STYLE type=\"text/css\"> "
								+ "body{ background-color: #FFFF; color: #606060; font-size: 13px; font-family: tahoma, verdana, arial, sans-serif; margin: 0; padding: 0; height: 100%; } "
								+ "table { background-color: #FFFFFF; font-size: 11px; }"
								+ "</STYLE></head><BODY><table border=1 width='100%' cellspacing=0 cellpadding=1 style='border: #ccc solid 1px;'>");
						html.append("<tr>");
						for (int i = 0; i < columns.length; i++) {
							html.append("<td nowrap=true><b>");
							html.append(columns[i].getText());
							html.append("</b></td>");

						}
						html.append("</tr>");
						for (int j = 0; j < stocksTable.getItemCount(); j++) {

							html.append("<tr>");
							for (int i = 0; i < columns.length; i++) {
								html.append("<td>");
								html.append(stocksTable.getItem(j).getText(i));
								html.append("&nbsp;</td>");
							}
							html.append("</tr>");
						}
						html.append("</table></BODY></HTML>");

						String name = _("Dialog.Stock.Print");
						DummyEditorInput editorInput = new DummyEditorInput(Application.ID.getUID(), name);
						editorInput.setData(html);
						page.openEditor(editorInput, HTMLPrintEditor.ID);
					} catch (PartInitException e) {
						Application.log.log(Level.OFF, "", e);
					}
				}
			};
			action.setToolTipText(_("Editor.Stock.Tooltip.Print"));
			action.setImageDescriptor(Activator.getImageDescriptor("icons/print.png"));
			form.getToolBarManager().add(action);
		}
		{
			Action action = new Action("refresh", Action.AS_PUSH_BUTTON) { //$NON-NLS-1$
				public void run() {
					refresh();
					refreshGrouping();
				}
			};
			action.setToolTipText(_("Editor.Stock.Tooltip.Refresh"));
			action.setImageDescriptor(Activator.getImageDescriptor("icons/refresh.png"));
			form.getToolBarManager().add(action);
		}
		form.updateToolBar();
		refresh();
		refreshGrouping();
	}

	@Override
	public boolean isDirty() {
		return false;
	}

	@Override
	public boolean isSaveAsAllowed() {
		return false;
	}

	@Override
	public void doSave(IProgressMonitor monitor) {}

	@Override
	public void doSaveAs() {}

}
